#include "viewmodelmanager.h"

ViewModelManager &ViewModelManager::instance()
{
    static ViewModelManager vm;
    return vm;
}

ViewModelManager::ViewModelManager()
{
    m_curViewModelPtr = nullptr;
    init(":/config/config.json");
}

void ViewModelManager::init(const QString &fileName)
{
//    // 使用工厂模式根据文件名的后缀创建对应的文件处理对象
//    QSharedPointer<BaseFileParser> parser =
//            QSharedPointer<BaseFileParser>(FileParserFactory::instance().createFileParser(fileName.toStdString()));
//    std::vector<std::string> viewModelType = parser->parserFile2Vec(fileName);
//    for(auto&& type:viewModelType){
//        // 这里初始化时，所有的指针都是nullptr，使用时才创建对象
//        m_viewModelMap[type] = nullptr;
//    }
}

void ViewModelManager::update(const std::string &nextViewModelName)
{
    switchView(nextViewModelName); // 通过反射创建viewmodel，反射还没实现
//    switchView<LoginViewModel>(); // 泛型创建viewmodel
}

void ViewModelManager::switchView(const std::string &viewModelName)
{
    auto nextViewModelItr = m_viewModelMap.find(viewModelName);
    if(nextViewModelItr == m_viewModelMap.end()){ // view 甚至不存在nullptr，出错
        qDebug() << "error: don't exist viewmodel: "<< QString::fromStdString(viewModelName);
        qDebug() << "try to create " << QString::fromStdString(viewModelName);
    }
    QSharedPointer<BaseViewModel> nextViewModelPtr;
    if(nextViewModelItr==m_viewModelMap.end() || nextViewModelItr->second == nullptr){
        // 不存在对象，则创建viewmodel，并更新map
        nextViewModelPtr = QSharedPointer<BaseViewModel>(ViewModelFactory::instance().createViewModel(viewModelName));
        nextViewModelPtr->setManager(this); // 创建后需要设置设置viewmodel的管理者为this
        m_viewModelMap[viewModelName] = nextViewModelPtr;
    }else{
        nextViewModelPtr = nextViewModelItr->second;
    }
    // m_curViewPtr存在时隐藏
    if(m_curViewModelPtr != nullptr){
        m_curViewModelPtr->hideView();
    }
    // 更新m_curView为nextView，展示nextView
    m_curViewModelPtr = nextViewModelPtr;
    m_curViewModelPtr->showView();
}

template<typename T>
void ViewModelManager::switchView()
{
    using ViewModelType = T;
    QSharedPointer<BaseViewModel> nextViewModelPtr(new ViewModelType(this));
    // 如果使用泛型实现而不是用反射+工厂，怎么使用map存储键值对？
    nextViewModelPtr->showView();
}
